package cn.wildfirechat.app.shiro;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.crypto.hash.Sha1Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;

@Component
public class CustomCredentialsMatcher implements CredentialsMatcher {

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        try {
            // 获取用户输入的明文密码
            String submittedPassword = (String) token.getCredentials();
            // 获取数据库中存储的加密密码
            String storedPassword = (String) info.getCredentials();

            // 从 AuthenticationInfo 中获取盐值
            String salt = null;
            if (info instanceof SimpleAuthenticationInfo) {
                SimpleAuthenticationInfo simpleInfo = (SimpleAuthenticationInfo) info;
                ByteSource saltBytes = simpleInfo.getCredentialsSalt();
                if (saltBytes != null) {
                    salt = new String(saltBytes.getBytes(), StandardCharsets.UTF_8);
                }
            }

            // 使用相同的加密逻辑验证密码
            return verifyPassword(submittedPassword, storedPassword, salt);

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    private boolean verifyPassword(String inputPassword, String storedPassword, String salt) throws Exception {
        MessageDigest digest = MessageDigest.getInstance(Sha1Hash.ALGORITHM_NAME);
        if (salt != null) {
            digest.reset();
            digest.update(salt.getBytes(StandardCharsets.UTF_8));
        }

        byte[] hashed = digest.digest(inputPassword.getBytes(StandardCharsets.UTF_8));
        String hashedPwd = Base64.getEncoder().encodeToString(hashed);
        return hashedPwd.equals(storedPassword);
    }
}